/*
Copyright 2011, CSE Shareware Foundation
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, 
   this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, 
   this list of conditions and the following disclaimer in the documentation 
   and/or other materials provided with the distribution.
 * Neither the name of CSE Shareware Foundation nor the names of its contributors 
   may be used to endorse or promote products derived from this software without 
   specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef _MANAGEDOBJ_H_CSEAPI_
#define _MANAGEDOBJ_H_CSEAPI_

#if defined(_MSC_VER) && _MSC_VER >= 1310
  #define CSE_PTR2ULONG(a)  ((__w64 unsigned long)(a))   // __w64 support from VC7.1
#else
  #define CSE_PTR2ULONG(a)  ((unsigned long)(a))
#endif

class CSE_IMPEXP_IN TMngInt: public TCseObj
{
public:
    TMngInt(): TCseObj(TIntObj(0)) { }
    TMngInt(const TMngInt& i): TCseObj(TIntObj(i.m_data->iValue)) { }
    TMngInt(TInt i): TCseObj(TIntObj(i)) { }

    const TMngInt& operator=(const TMngInt& i) const { m_data->iValue = i.m_data->iValue; return *this; }
    const TMngInt& operator=(TInt i) const { m_data->iValue = i; return *this; }

    TIntObj& iObj() const { return (TIntObj&) m_data->iValue; }
    operator TInt() const { return m_data->iValue; }

    const TMngInt& operator++() const { m_data->iValue++; return *this; }     // prefix
    const TMngInt& operator++(int) const { m_data->iValue++; return *this; }  // postfix
    const TMngInt& operator--() const { m_data->iValue--; return *this; }     // prefix
    const TMngInt& operator--(int) const { m_data->iValue--; return *this; }  // postfix

    void operator*=(TInt i) const  { m_data->iValue *= i; }
    void operator/=(TInt i) const  { m_data->iValue /= i; }
    void operator%=(TInt i) const  { m_data->iValue %= i; }
    void operator+=(TInt i) const  { m_data->iValue += i; }
    void operator-=(TInt i) const  { m_data->iValue -= i; }
    void operator<<=(TInt i) const { m_data->iValue <<= i; }
    void operator>>=(TInt i) const { m_data->iValue >>= i; }
    void operator&=(TInt i) const  { m_data->iValue &= i; }
    void operator|=(TInt i) const  { m_data->iValue |= i; }
    void operator^=(TInt i) const  { m_data->iValue ^= i; }

    TInt operator*(TInt i) const { return m_data->iValue * i; }
    TInt operator/(TInt i) const { return m_data->iValue / i; }
    TInt operator%(TInt i) const { return m_data->iValue % i; }
    TInt operator+(TInt i) const { return m_data->iValue + i; }
    TInt operator-(TInt i) const { return m_data->iValue - i; }
    TInt operator<<(TInt i) const { return m_data->iValue << i; }
    TInt operator>>(TInt i) const { return m_data->iValue >> i; }
    TInt operator&(TInt i) const { return m_data->iValue & i; }
    TInt operator|(TInt i) const { return m_data->iValue | i; }
    TInt operator^(TInt i) const { return m_data->iValue ^ i; }
};

extern CSE_IMPEXP_IN TInt operator*(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator/(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator%(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator+(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator-(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator<<(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator>>(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator&(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator|(TInt i1,const TMngInt& i2);
extern CSE_IMPEXP_IN TInt operator^(TInt i1,const TMngInt& i2);

class CSE_IMPEXP_IN TMngWint: public TCseObj
{
public:
    TMngWint(): TCseObj(TWintObj(0)) { }
    TMngWint(const TMngWint& i): TCseObj(TWintObj(i.m_data->wValue)) { }
    TMngWint(TWint i): TCseObj(TWintObj(i)) { }

    const TMngWint& operator=(const TMngWint& i) const { m_data->wValue = i.m_data->wValue; return *this; }
    const TMngWint& operator=(TWint i) const { m_data->wValue = i; return *this; }

    TWintObj& wObj() const { return (TWintObj&) m_data->wValue; }
    operator TWint() const { return m_data->wValue; }

    const TMngWint& operator++() const { m_data->wValue++; return *this; }     // prefix
    const TMngWint& operator++(int) const { m_data->wValue++; return *this; }  // postfix
    const TMngWint& operator--() const { m_data->wValue--; return *this; }     // prefix
    const TMngWint& operator--(int) const { m_data->wValue--; return *this; }  // postfix

    void operator*=(TWint i) const { m_data->wValue *= i; }
    void operator/=(TWint i) const { m_data->wValue /= i; }
    void operator%=(TWint i) const { m_data->wValue %= i; }
    void operator+=(TWint i) const { m_data->wValue += i; }
    void operator-=(TWint i) const { m_data->wValue -= i; }
    void operator<<=(TInt i) const { m_data->wValue <<= i; }
    void operator>>=(TInt i) const { m_data->wValue >>= i; }
    void operator&=(TWint i) const { m_data->wValue &= i; }
    void operator|=(TWint i) const { m_data->wValue |= i; }
    void operator^=(TWint i) const { m_data->wValue ^= i; }

    TWint operator*(TWint i) const { return m_data->wValue * i; }
    TWint operator/(TWint i) const { return m_data->wValue / i; }
    TWint operator%(TWint i) const { return m_data->wValue % i; }
    TWint operator+(TWint i) const { return m_data->wValue + i; }
    TWint operator-(TWint i) const { return m_data->wValue - i; }
    TWint operator<<(TInt i) const { return m_data->wValue << i; }
    TWint operator>>(TInt i) const { return m_data->wValue >> i; }
    TWint operator&(TWint i) const { return m_data->wValue & i; }
    TWint operator|(TWint i) const { return m_data->wValue | i; }
    TWint operator^(TWint i) const { return m_data->wValue ^ i; }
};

extern CSE_IMPEXP_IN TWint operator*(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator/(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator%(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator+(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator-(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator<<(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator>>(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator&(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator|(TWint i1,const TMngWint& i2);
extern CSE_IMPEXP_IN TWint operator^(TWint i1,const TMngWint& i2);

class CSE_IMPEXP_IN TMngFloat: public TCseObj
{
public:
    TMngFloat(): TCseObj(TFloatObj(0.0)) { }
    TMngFloat(const TMngFloat& f): TCseObj(TFloatObj(f.m_data->fValue)) { }
    TMngFloat(TDouble f): TCseObj(TFloatObj(f)) { }
    
    const TMngFloat& operator=(const TMngFloat& f) const { m_data->fValue = f.m_data->fValue; return *this; }
    const TMngFloat& operator=(TDouble f) const { m_data->fValue = f; return *this; }

    TFloatObj& fObj() const { return (TFloatObj&) m_data->fValue; }
    operator TDouble() const { return m_data->fValue; }

    const TMngFloat& operator++() const { m_data->fValue++; return *this; }     // prefix
    const TMngFloat& operator++(int) const { m_data->fValue++; return *this; }  // postfix
    const TMngFloat& operator--() const { m_data->fValue--; return *this; }     // prefix
    const TMngFloat& operator--(int) const { m_data->fValue--; return *this; }  // postfix

    void operator*=(TDouble f) const { m_data->fValue *= f; }
    void operator/=(TDouble f) const { m_data->fValue /= f; }
    void operator+=(TDouble f) const { m_data->fValue += f; }
    void operator-=(TDouble f) const { m_data->fValue -= f; }
    
    TDouble operator*(TDouble f) const { return m_data->fValue * f; }
    TDouble operator/(TDouble f) const { return m_data->fValue / f; }
    TDouble operator+(TDouble f) const { return m_data->fValue + f; }
    TDouble operator-(TDouble f) const { return m_data->fValue - f; }
};

extern CSE_IMPEXP_IN TDouble operator-(TDouble f1,const TMngFloat& f2);
extern CSE_IMPEXP_IN TDouble operator*(TDouble f1,const TMngFloat& f2);
extern CSE_IMPEXP_IN TDouble operator/(TDouble f1,const TMngFloat& f2);
extern CSE_IMPEXP_IN TDouble operator+(TDouble f1,const TMngFloat& f2);

class CSE_IMPEXP_IN TMngStr: public TCseObj
{
public:
    TMngStr(): TCseObj(CseEmptyStr) { }
    TMngStr(const TMngStr& s): TCseObj(s.sArray()) { }
    TMngStr(const TCharArray& s): TCseObj(s) { }
    TMngStr(TXchar ch, int count=1) { TCharArray s(ch,count); m_data = TCseObj(CUT_FROM,s).transfer(dummy); }
    TMngStr(const TXchar* pSour, int n=-1, int iExt=0) { TCharArray s(pSour,n,iExt); m_data = TCseObj(CUT_FROM,s).transfer(dummy); }

    TMngStr(int MagicNum, TMngStr& str): TCseObj(MagicNum,str.sArray()) { }
    TMngStr(int MagicNum, TCharArray& str): TCseObj(MagicNum,str) { }

    const TMngStr& join(const TMngStr& str, int index=0) const { sArray().join(str.sArray(),index); return *this; }
    const TMngStr& join(const TCharArray& str, int index=0) const { sArray().join(str,index); return *this; }

    const TMngStr& operator=(const TMngStr& s) const { sArray() = s.sArray(); return *this; }
    const TMngStr& operator=(const TCharArray& str) const { sArray() = str; return *this; }
    const TMngStr& operator=(const TXchar *s) const { sArray() = s; return *this; }
    const TMngStr& operator=(TXchar ch) const { sArray() = ch; return *this; }

    void operator+=(const TMngStr& str) const { sArray() += str.sArray(); }
    void operator+=(const TCharArray& str) const { sArray() += str; }
    void operator+=(const TXchar* pSour) const { sArray() += pSour; }
    void operator+=(TXchar ch) const { sArray() += ch; }
    TCharArray multi(int n) const { return sArray().multi(n); }

    TCharArray& sArray() const { return (TCharArray&) m_data->sValue; }
    
    operator TXchar*() const { return m_data->sValue; }
    TXchar& sub(int index) const { return sArray().sub(index); }
    TXchar& operator[](int index) const { return sArray().sub(index); }
    
    TXchar *addr() const { return sArray().addr(); }
    int len() const { return sArray().len(); }
    TBool isEmpty() const { return sArray().isEmpty(); }
    TInt compare(const TMngStr& sOther) const { return sArray().compare(sOther.sArray()); }
    TInt compare(const TCharArray& sOther) const { return sArray().compare(sOther); }
    TInt compare(const TXchar *pOther) const { return sArray().compare(pOther); }

    TCharArray slice(int index, int iLen=-1) const { return sArray().slice(index,iLen); }

    void exchange(TMngStr& other) const { sArray().exchange(other.sArray()); }
    void exchange(TCharArray& other) const { sArray().exchange(other); }
    TXchar append(TXchar ch) const { return sArray().append(ch); }
    TCharArray& add(TXchar ch, int *pIndex=NULL) const { return sArray().add(ch,pIndex); }
    const TIntObj& insert(int index, const TIntObj& obj) const { return sArray().insert(index,obj); }
    void insertSlice(int index, const TXchar *pSour, int iLen=-1) const { sArray().insertSlice(index,pSour,iLen); }
    void remove(int index, int iLen=1) const { sArray().remove(index,iLen); }

    void clear() const { sArray().clear(); }
    int truncate(int iLen) const { return sArray().truncate(iLen); }
    int sortAdd(TXchar ch) const { return sArray().sortAdd(ch); }
    void sort() const { sArray().sort(); }

    static TMngStr format(const TXchar *frmt, ...)
    { va_list ArgPtr; va_start(ArgPtr,frmt); TCharArray s = TCharArray::vformat(frmt,ArgPtr); return TMngStr(CUT_FROM,s); }

    void resize(int iSize) const { sArray().resize(iSize); }
    TUint32 hash() const { return sArray().hash(); }
    TCharArray str(TXchar pre=_T('"')) const { return sArray().str(pre); }

    TBool toInt(TInt& ret) const { return sArray().toInt(ret); }
    TBool toWint(TInt64& ret) const { return sArray().toWint(ret); }
    TBool toDouble(TDouble& ret) const { return sArray().toDouble(ret); }

    const TMngStr& upper() const { sArray().upper(); return *this; }
    const TMngStr& lower() const { sArray().lower(); return *this; }
    TCharArray toUpper() const { return sArray().toUpper(); }
    TCharArray toLower() const { return sArray().toLower(); }

    int trim() const { return sArray().trim(); }
    int trimLeft() const { return sArray().trimLeft(); }
    int trimRight() const { return sArray().trimRight(); }
    int find(TXchar ch, int from=0) const { return sArray().find(ch,from); }
    int find(const TXchar *sSub, int from=0) const { return sArray().find(sSub,from); }
    
    TBool enumItem(void*& pIter, TXchar *pRet=NULL) const { return sArray().enumItem(pIter,pRet); }
    
    int count(const TXchar* sSub, int iStart=0, int iEnd=0) const { return sArray().count(sSub,iStart,iEnd); }
    const TMngStr& align(int iWidth, TXchar fillChar = _T(' ')) const { sArray().align(iWidth,fillChar); return *this; }
    const TMngStr& alignLeft(int iWidth, TXchar fillChar = _T(' ')) const { sArray().alignLeft(iWidth,fillChar); return *this; }
    const TMngStr& alignRight(int iWidth, TXchar fillChar = _T(' ')) const { sArray().alignRight(iWidth,fillChar); return *this; } 
    const TMngStr& replace(const TXchar *sSub, const TXchar *sNew, int count=-1) const { sArray().replace(sSub,sNew,count); return *this; }
    
    TObjArray split(const TXchar* sSep=NULL, int count=-1) const { return sArray().split(sSep,count); }
    TObjArray splitLines(TBool keepEnds=false, int count=-1) const { return sArray().splitLines(keepEnds,count); }

    TCharArray operator+(const TMngStr& y) const { return sArray() + y.sArray(); }
    TCharArray operator+(const TXchar *y) const { return sArray() + y; }
    TCharArray operator+(TXchar y) const { return sArray() + y; }
    TCharArray operator+(const TCharArray& y) const { return sArray() + y; }

    TBool operator==(const TXchar *y) const { return sArray() == y; }
    TBool operator!=(const TXchar *y) const { return sArray() != y; }
    TBool operator>(const TXchar *y) const { return sArray() > y; }
    TBool operator>=(const TXchar *y) const { return sArray() >= y; }
    TBool operator<(const TXchar *y) const { return sArray() < y; }
    TBool operator<=(const TXchar *y) const { return sArray() <= y; }
};

extern CSE_IMPEXP_IN TCharArray operator+(TXchar x, const TMngStr& y);
extern CSE_IMPEXP_IN TCharArray operator+(const TXchar *x, const TMngStr& y);
extern CSE_IMPEXP_IN TCharArray operator+(const TCharArray& x, const TMngStr& y);

extern CSE_IMPEXP_IN TBool operator==(const TXchar *x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator==(const TCharArray& x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator!=(const TXchar *x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator!=(const TCharArray& x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator>(const TXchar *x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator>(const TCharArray& x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator>=(const TXchar *x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator>=(const TCharArray& x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator<(const TXchar *x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator<(const TCharArray& x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator<=(const TXchar *x, const TMngStr& y);
extern CSE_IMPEXP_IN TBool operator<=(const TCharArray& x, const TMngStr& y);

class CSE_IMPEXP_IN TMngTier: public TCseObj
{
protected:
    TMngTier(CseObj data): TCseObj(data) { if (Cse_type(m_data) != dtTier) throw LOG_CSE_ERR(CSE_TYPE_ERR,_T("content of TMngTier should be dtTier")); }

    TBool setExitFunc(void* AFunc) {
        if (len() >= 1) {
            sub(0) = (TInt) CSE_PTR2ULONG(AFunc);
            setOption(18);
            return true;
        }
        else return false;
    }

    void __exit__() { }

public:
    class m { protected:
        TInt onExit;
    };

    TMngTier(): TCseObj(CseEmptyTier) { }
    TMngTier(const TMngTier& t): TCseObj(t.tArray()) { }
    TMngTier(const TIntArray& t): TCseObj(t) { }
    TMngTier(int count) { TIntArray t(count); m_data = TCseObj(CUT_FROM,t).transfer(dummy); }
    TMngTier(const TInt* pSour, int n, int iExt=0) { TIntArray t(pSour,n,iExt); m_data = TCseObj(CUT_FROM,t).transfer(dummy); }

    TMngTier(int MagicNum, TMngTier& tier): TCseObj(MagicNum,tier.tArray()) { }
    TMngTier(int MagicNum, TIntArray& tier): TCseObj(MagicNum,tier) { }

    const TMngTier& join(const TMngTier& t, int index=0) const { tArray().join(t.tArray(),index); return *this; }
    const TMngTier& join(const TIntArray& t, int index=0) const { tArray().join(t,index); return *this; }

    const TMngTier& operator=(const TMngTier& t) const { tArray() = t.tArray(); return *this; }
    const TMngTier& operator=(const TIntArray& t) const { tArray() = t; return *this; }

    void operator+=(const TMngTier& t) const { tArray() += t.tArray(); }
    void operator+=(const TIntArray& t) const { tArray() += t; }
    void operator+=(TInt i) const { tArray() += i; }
    TIntArray multi(int n) const { return tArray().multi(n); }

    TIntArray& tArray() const { return (TIntArray&) m_data->tValue; }

    TInt& sub(int index) const { return tArray().sub(index); }
    TInt& operator[](int index) const { return tArray().sub(index); }

    TInt *addr() const { return tArray().addr(); }
    int len() const { return tArray().len(); }
    TBool isEmpty() const { return tArray().isEmpty(); }
    TInt compare(const TMngTier& t) const { return tArray().compare(t.tArray()); }
    TInt compare(const TIntArray& t) const { return tArray().compare(t); }

    TIntArray slice(int index, int iLen=-1) const { return tArray().slice(index,iLen); }

    static TMngTier format(int ArgNum, ...)
    { va_list ArgPtr; va_start(ArgPtr,ArgNum); TIntArray t = TIntArray::vformat(ArgNum,ArgPtr); return TMngTier(CUT_FROM,t); }

    void exchange(TMngTier& other) const { tArray().exchange(other.tArray()); }
    void exchange(TIntArray& other) const { tArray().exchange(other); }
    TInt append(TInt i) const { return tArray().append(i); }
    TIntArray& add(TInt i, int *pIndex=NULL) const { return tArray().add(i,pIndex); }
    const TIntObj& insert(int index, const TIntObj& obj) const { return tArray().insert(index,obj); }
    void insertSlice(int index, const TInt *pSour, int iLen) const { tArray().insertSlice(index,pSour,iLen); }
    void remove(int index, int iLen=1) const { tArray().remove(index,iLen); }

    void clear() const { tArray().clear(); }
    int truncate(int iLen) const { return tArray().truncate(iLen); }
    int sortAdd(TInt iValue) const { return tArray().sortAdd(iValue); }
    void sort() const { tArray().sort(); }

    int find(TInt iValue, int from=0) const { return tArray().find(iValue,from); }
    void resize(int iSize) const { tArray().resize(iSize); }
    TCharArray str() const { return tArray().str(); }
    
    TBool enumItem(void*& pIter, TInt *pRet=NULL) const { return tArray().enumItem(pIter,pRet); }

    TBool operator==(const TMngTier& y) const { return tArray() == y.tArray(); }
    TBool operator==(const TIntArray& y) const { return tArray() == y; }
    TBool operator!=(const TMngTier& y) const { return tArray() != y.tArray(); }
    TBool operator!=(const TIntArray& y) const { return tArray() != y; }
    TBool operator>(const TMngTier& y) const { return tArray() > y.tArray(); }
    TBool operator>(const TIntArray& y) const { return tArray() > y; }
    TBool operator>=(const TMngTier& y) const { return tArray() >= y.tArray(); }
    TBool operator>=(const TIntArray& y) const { return tArray() >= y; }
    TBool operator<(const TMngTier& y) const { return tArray() < y.tArray(); }
    TBool operator<(const TIntArray& y) const { return tArray() < y; }
    TBool operator<=(const TMngTier& y) const { return tArray() <= y.tArray(); }
    TBool operator<=(const TIntArray& y) const { return tArray() <= y; }
};

extern CSE_IMPEXP_IN TBool operator==(const TIntArray& x, const TMngTier& y);
extern CSE_IMPEXP_IN TBool operator!=(const TIntArray& x, const TMngTier& y);
extern CSE_IMPEXP_IN TBool operator>(const TIntArray& x, const TMngTier& y);
extern CSE_IMPEXP_IN TBool operator>=(const TIntArray& x, const TMngTier& y);
extern CSE_IMPEXP_IN TBool operator<(const TIntArray& x, const TMngTier& y);
extern CSE_IMPEXP_IN TBool operator<=(const TIntArray& x, const TMngTier& y);

class CSE_IMPEXP_IN TMngBuff: public TCseObj
{
protected:
    TMngBuff(CseObj data): TCseObj(data) { if (Cse_type(m_data) != dtBuff) throw LOG_CSE_ERR(CSE_TYPE_ERR,_T("content of TMngBuff should be dtBuff")); }

    TBool setExitFunc(void* AFunc) {
        if (len() >= 1) {
            sub(0) = TIntObj((TInt) CSE_PTR2ULONG(AFunc));
            setOption(18);
            return true;
        }
        else return false;
    }

    void __exit__() { }

public:
    class m { protected:
        TMngInt onExit;
    };

    TMngBuff(): TCseObj(CseEmptyBuff) { }
    TMngBuff(const TMngBuff& b): TCseObj(b.bArray()) { }
    TMngBuff(const TObjArray& b): TCseObj(b) { }
    TMngBuff(int count) { TObjArray b(count); m_data = TCseObj(CUT_FROM,b).transfer(dummy); }
    TMngBuff(const CseObj* pSour, int n, int iExt=0) { TObjArray b(pSour,n,iExt); m_data = TCseObj(CUT_FROM,b).transfer(dummy); }
    
    TMngBuff(int MagicNum, TMngBuff& buff): TCseObj(MagicNum,buff.bArray()) { }
    TMngBuff(int MagicNum, TObjArray& buff): TCseObj(MagicNum,buff) { }

    const TMngBuff& join(const TMngBuff& b, int index=0) const { bArray().join(b.bArray(),index); return *this; }
    const TMngBuff& join(const TObjArray& b, int index=0) const { bArray().join(b,index); return *this; }

    const TMngBuff& operator=(const TMngBuff& b) const { bArray() = b.bArray(); return *this; }
    const TMngBuff& operator=(const TObjArray& b) const { bArray() = b; return *this; }

    void operator+=(const TMngBuff& b) const { bArray() += b.bArray(); }
    void operator+=(const TObjArray& b) const { bArray() += b; }
    void operator+=(const TCseObj& obj) const { bArray() += obj; }
    TObjArray multi(int n) const { return bArray().multi(n); }

    TObjArray& bArray() const { return (TObjArray&) m_data->bValue; }
    TCseObj& sub(int index) const { return bArray().sub(index); }
    TCseObj& operator[](int index) const { return bArray().sub(index); }

    CseObj *addr() const { return bArray().addr(); }
    int len() const { return bArray().len(); }
    TBool isEmpty() const { return bArray().isEmpty(); }
    TInt compare(const TMngBuff& other) const { return bArray().compare(other.bArray()); }
    TInt compare(const TObjArray& other) const { return bArray().compare(other); }
    
    TObjArray slice(int index, int iLen=-1) const { return bArray().slice(index,iLen); }

    static TMngBuff format(int ArgNum, ...)
    { va_list ArgPtr; va_start(ArgPtr,ArgNum); TObjArray b = TObjArray::vformat(ArgNum,ArgPtr); return TMngBuff(CUT_FROM,b); }

    void exchange(TMngBuff& other) const { bArray().exchange(other.bArray()); }
    void exchange(TObjArray& other) const { bArray().exchange(other); }
    const TCseObj& append(const TCseObj& obj) const { return bArray().append(obj); }
    TObjArray& add(const TCseObj& obj, int *pIndex=NULL) const { return bArray().add(obj,pIndex); }
    const TCseObj& insert(int index, const TCseObj& obj) const { return bArray().insert(index,obj); }
    void insertSlice(int index, const CseObj *pSour, int iSourLen) const { bArray().insertSlice(index,pSour,iSourLen); }

    void remove(int index, int iLen=1) const { bArray().remove(index,iLen); }
    TCseObj pop(int index=-1) const { return bArray().pop(index); }

    void clear() const { bArray().clear(); }
    int truncate(int iLen) const { return bArray().truncate(iLen); }
    int sortAdd(const TCseObj& obj) const { return bArray().sortAdd(obj); }
    void sort() const { bArray().sort(); }

    int find(const TCseObj& vSub, int from=0) const { return bArray().find(vSub,from); }
    void resize(int iSize) const { bArray().resize(iSize); }
    TCharArray str() const { return bArray().str(); }
    
    TBool enumItem(void*& pIter, TCseObj *pRet=NULL) const { return bArray().enumItem(pIter,pRet); }

    TBool operator==(const TMngBuff& y) const { return bArray() == y.bArray(); }
    TBool operator==(const TObjArray& y) const { return bArray() == y; }
    TBool operator!=(const TMngBuff& y) const { return bArray() != y.bArray(); }
    TBool operator!=(const TObjArray& y) const { return bArray() != y; }
    TBool operator>(const TMngBuff& y) const { return bArray() > y.bArray(); }
    TBool operator>(const TObjArray& y) const { return bArray() > y; }
    TBool operator>=(const TMngBuff& y) const { return bArray() >= y.bArray(); }
    TBool operator>=(const TObjArray& y) const { return bArray() >= y; }
    TBool operator<(const TMngBuff& y) const { return bArray() < y.bArray(); }
    TBool operator<(const TObjArray& y) const { return bArray() < y; }
    TBool operator<=(const TMngBuff& y) const { return bArray() <= y.bArray(); }
    TBool operator<=(const TObjArray& y) const { return bArray() <= y; }
};

extern CSE_IMPEXP_IN TBool operator==(const TObjArray& x, const TMngBuff& y);
extern CSE_IMPEXP_IN TBool operator!=(const TObjArray& x, const TMngBuff& y);
extern CSE_IMPEXP_IN TBool operator>(const TObjArray& x, const TMngBuff& y);
extern CSE_IMPEXP_IN TBool operator>=(const TObjArray& x, const TMngBuff& y);
extern CSE_IMPEXP_IN TBool operator<(const TObjArray& x, const TMngBuff& y);
extern CSE_IMPEXP_IN TBool operator<=(const TObjArray& x, const TMngBuff& y);
    
class CSE_IMPEXP_IN TMngDict: public TCseObj
{
public:
    TMngDict(): TCseObj(CseEmptyDict) { }
    TMngDict(const TMngDict& d): TCseObj(d.dArray()) { }
    TMngDict(const TEntryArray& d): TCseObj(d) { }
    TMngDict(int n) { TEntryArray d(n); TCseObj(CUT_FROM,d).transfer(dummy); }
    TMngDict(PEntryPoint pSour) { TEntryArray d(pSour); m_data = TCseObj(CUT_FROM,d).transfer(dummy); }
    
    TMngDict(int MagicNum, TMngDict& dict): TCseObj(MagicNum,dict.dArray()) { }
    TMngDict(int MagicNum, TEntryArray& dict): TCseObj(MagicNum,dict) { }

    const TMngDict& join(const TMngDict& entry) const { dArray().join(entry.dArray()); return *this; }
    const TMngDict& join(const TEntryArray& entry) const { dArray().join(entry); return *this; }

    const TMngDict& operator=(const TMngDict& entry) const { dArray() = entry.dArray(); return *this; }
    const TMngDict& operator=(const TEntryArray& entry) const { dArray() = entry; return *this; }
    void operator+=(const TMngDict& entry) const { dArray() += entry.dArray(); }
    void operator+=(const TEntryArray& entry) const { dArray() += entry; }

    TEntryArray& dArray() const { return (TEntryArray&) m_data->entry; }

    static TMngDict format(int ArgNum, ...)
    { va_list ArgPtr; va_start(ArgPtr,ArgNum); TEntryArray d = TEntryArray::vformat(ArgNum,ArgPtr); return TMngDict(CUT_FROM,d); }

    PEntryPoint addr() const { return dArray().addr(); }
    int len() const { return dArray().len(); }
    TBool isEmpty() const { return dArray().isEmpty(); }
    TInt compare(const TMngDict& dOther) const { return dArray().compare(dOther.dArray()); }
    TInt compare(const TEntryArray& dOther) const { return dArray().compare(dOther); }

    TCseObj get(const TCseObj& key) const { return dArray().get(key); }
    const TCseObj& set(const TCseObj& key, const TCseObj& value) const { return dArray().set(key,value); }
    TCseObj getEx(const TCseObj& key, const TCseObj& vDefault) const { return dArray().getEx(key,vDefault); }
    TCseObj setEx(const TCseObj& key, const TCseObj& value) const { return dArray().setEx(key,value); }
    TBool hasKey(const TCseObj& key) const { return dArray().hasKey(key); }

    void exchange(TMngDict& other) const { dArray().exchange(other.dArray()); }
    void exchange(TEntryArray& other) const { dArray().exchange(other); }
    void clear() const { dArray().clear(); }
    TCharArray str() const { return dArray().str(); }

    const TCseObj& bind(const TCseObj& value) const { return dArray().bind(value); }
    TCseObj getBinding() const { return dArray().getBinding(); }
    int fixSize(int iRsvd=0) const { return dArray().fixSize(iRsvd); }

    // start with pEntry = NULL
    TBool enumItem(PEntryPoint& pEntry, TCseObj *pKey=NULL, TCseObj *pValue=NULL) const 
    { return dArray().enumItem(pEntry,pKey,pValue); }
    TObjArray keys() const { return dArray().keys(); }
    TObjArray keyValues() const { return dArray().keyValues(); }

    TBool operator==(const TMngDict& y) const { return dArray() == y.dArray(); }
    TBool operator==(const TEntryArray& y) const { return dArray() == y; }
    TBool operator!=(const TMngDict& y) const { return dArray() != y.dArray(); }
    TBool operator!=(const TEntryArray& y) const { return dArray() != y; }
};

extern CSE_IMPEXP_IN TBool operator==(const TEntryArray& x, const TMngDict& y);
extern CSE_IMPEXP_IN TBool operator!=(const TEntryArray& x, const TMngDict& y);

template <class T,int n> class TMngArray: public TMngBuff
{
#ifndef MNG_OPEN_NEWDEL
private:
    static void* operator new(size_t);
    static void* operator new(size_t,int);
    static void operator delete(void*);
    static void operator delete(void*,size_t);
    const TMngArray* operator&() const;
#endif
public:
    TMngArray(): TMngBuff((const CseObj*)NULL,0,n) { }
    TMngArray(const TMngArray& b): TMngBuff(b.m_data) { }

    T& sub(int i) const { return (T&) TMngBuff::sub(i); }
    T& operator[](int i) const { return (T&) TMngBuff::sub(i); }
};

class CSE_IMPEXP_IN TIntProp: public TCseObj
{
private:
#ifndef MNG_OPEN_NEWDEL
    TIntProp *operator&();     // get prop-value address disabled
#endif
    TInt value_(TInt *pValue=NULL) const
    {
        CseObj v = m_data->bValue[1];
        if (v->bHold)
            return ((TInt (*)(CseObj,TIntObj&,TInt*))v->bHold)(v->vValue,(TIntObj&)m_data->bValue[0]->iValue,pValue);
        else {
            if (pValue != NULL)
                m_data->bValue[0]->iValue = *pValue;
            return m_data->bValue[0]->iValue;
        }
    }

public:
    TIntProp(): TCseObj(CseEmptyBuff) { append(TIntObj(0)); append(TIntObj(0)); }
    TIntProp(const TIntProp& i): TCseObj(i.bArray()) { }
    TIntProp(TInt i): TCseObj(CseEmptyBuff) { append(TIntObj(i)); append(TIntObj(0)); }

    void bindMethod(void *owner, void *AccessFunc=NULL) const
    { ASSERT_TRUE(len() == 2); m_data->bValue[1]->vValue = (CseObj)owner; m_data->bValue[1]->bHold = (CseObj)AccessFunc; }

    TIntObj& iObj() const { return (TIntObj&) m_data->bValue[0]->iValue; }

    const TIntProp& operator=(const TIntProp& i) const { TInt ii = i.value_(); value_(&ii); return *this; }
    const TIntProp& operator=(TInt i) const { value_(&i); return *this; }

    operator TInt() const { return value_(); }

    const TIntProp& operator++() const { TInt i = value_() + 1; value_(&i); return *this; }     // prefix
    const TIntProp& operator++(int) const { TInt i = value_() + 1; value_(&i); return *this; }  // postfix
    const TIntProp& operator--() const { TInt i = value_() - 1; value_(&i); return *this; }     // prefix
    const TIntProp& operator--(int) const { TInt i = value_() - 1; value_(&i); return *this; }  // postfix

    void operator*=(TInt i) const  { i = value_() * i; value_(&i); }
    void operator/=(TInt i) const  { i = value_() / i; value_(&i); }
    void operator%=(TInt i) const  { i = value_() % i; value_(&i); }
    void operator+=(TInt i) const  { i = value_() + i; value_(&i); }
    void operator-=(TInt i) const  { i = value_() - i; value_(&i); }
    void operator<<=(TInt i) const { i = value_() << i; value_(&i); }
    void operator>>=(TInt i) const { i = value_() >> i; value_(&i); }
    void operator&=(TInt i) const  { i = value_() & i; value_(&i); }
    void operator|=(TInt i) const  { i = value_() | i; value_(&i); }
    void operator^=(TInt i) const  { i = value_() ^ i; value_(&i); }

    TInt operator*(TInt i) const { return value_() * i; }
    TInt operator/(TInt i) const { return value_() / i; }
    TInt operator%(TInt i) const { return value_() % i; }
    TInt operator+(TInt i) const { return value_() + i; }
    TInt operator-(TInt i) const { return value_() - i; }
    TInt operator<<(TInt i) const { return value_() << i; }
    TInt operator>>(TInt i) const { return value_() >> i; }
    TInt operator&(TInt i) const { return value_() & i; }
    TInt operator|(TInt i) const { return value_() | i; }
    TInt operator^(TInt i) const { return value_() ^ i; }
};

extern CSE_IMPEXP_IN TInt operator*(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator/(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator%(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator+(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator-(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator<<(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator>>(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator&(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator|(TInt i1,const TIntProp& i2);
extern CSE_IMPEXP_IN TInt operator^(TInt i1,const TIntProp& i2);

class CSE_IMPEXP_IN TWintProp: public TCseObj
{
private:
#ifndef MNG_OPEN_NEWDEL
    TWintProp *operator&();     // get prop-value address disabled
#endif
    TWint value_(TWint *pValue=NULL) const
    {
        CseObj v = m_data->bValue[1];
        if (v->bHold)
            return ((TWint (*)(CseObj,TWintObj&,TWint*))v->bHold)(v->vValue,(TWintObj&)m_data->bValue[0]->wValue,pValue);
        else {
            if (pValue != NULL)
                m_data->bValue[0]->wValue = *pValue;
            return m_data->bValue[0]->wValue;
        }
    }

public:
    TWintProp(): TCseObj(CseEmptyBuff) { append(TWintObj(0)); append(TIntObj(0)); }
    TWintProp(const TWintProp& i): TCseObj(i.bArray()) { }
    TWintProp(TWint i): TCseObj(CseEmptyBuff) { append(TWintObj(i)); append(TIntObj(0)); }

    void bindMethod(void *owner, void *AccessFunc=NULL) const
    { ASSERT_TRUE(len() == 2); m_data->bValue[1]->vValue = (CseObj)owner; m_data->bValue[1]->bHold = (CseObj)AccessFunc; }

    TWintObj& wObj() const { return (TWintObj&) m_data->bValue[0]->wValue; }

    const TWintProp& operator=(const TWintProp& i) const { TWint ii = i.value_(); value_(&ii); return *this; }
    const TWintProp& operator=(TWint i) const { value_(&i); return *this; }

    operator TWint() const { return value_(); }

    const TWintProp& operator++() const { TWint i = value_() + 1; value_(&i); return *this; }     // prefix
    const TWintProp& operator++(int) const { TWint i = value_() + 1; value_(&i); return *this; }  // postfix
    const TWintProp& operator--() const { TWint i = value_() - 1; value_(&i); return *this; }     // prefix
    const TWintProp& operator--(int) const { TWint i = value_() - 1; value_(&i); return *this; }  // postfix

    void operator*=(TWint i) const { i = value_() * i; value_(&i); }
    void operator/=(TWint i) const { i = value_() / i; value_(&i); }
    void operator%=(TWint i) const { i = value_() % i; value_(&i); }
    void operator+=(TWint i) const { i = value_() + i; value_(&i); }
    void operator-=(TWint i) const { i = value_() - i; value_(&i); }
    void operator<<=(TInt i) const { TWint ii = value_() << i; value_(&ii); }
    void operator>>=(TInt i) const { TWint ii = value_() >> i; value_(&ii); }
    void operator&=(TWint i) const { i = value_() & i; value_(&i); }
    void operator|=(TWint i) const { i = value_() | i; value_(&i); }
    void operator^=(TWint i) const { i = value_() ^ i; value_(&i); }

    TWint operator*(TWint i) const { return value_() * i; }
    TWint operator/(TWint i) const { return value_() / i; }
    TWint operator%(TWint i) const { return value_() % i; }
    TWint operator+(TWint i) const { return value_() + i; }
    TWint operator-(TWint i) const { return value_() - i; }
    TWint operator<<(TInt i) const { return value_() << i; }
    TWint operator>>(TInt i) const { return value_() >> i; }
    TWint operator&(TWint i) const { return value_() & i; }
    TWint operator|(TWint i) const { return value_() | i; }
    TWint operator^(TWint i) const { return value_() ^ i; }
};

extern CSE_IMPEXP_IN TWint operator*(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator/(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator%(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator+(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator-(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator<<(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator>>(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator&(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator|(TWint i1,const TWintProp& i2);
extern CSE_IMPEXP_IN TWint operator^(TWint i1,const TWintProp& i2);

class CSE_IMPEXP_IN TFloatProp: public TCseObj
{
private:
#ifndef MNG_OPEN_NEWDEL
    TFloatProp *operator&();     // get prop-value address disabled
#endif
    TDouble value_(TDouble *pValue=NULL) const
    {
        CseObj v = m_data->bValue[1];
        if (v->bHold)
            return ((TDouble (*)(CseObj,TFloatObj&,TDouble*))v->bHold)(v->vValue,(TFloatObj&)m_data->bValue[0]->fValue,pValue);
        else {
            if (pValue != NULL)
                m_data->bValue[0]->fValue = *pValue;
            return m_data->bValue[0]->fValue;
        }
    }

public:
    TFloatProp(): TCseObj(CseEmptyBuff) { append(TFloatObj(0.0)); append(TIntObj(0)); }
    TFloatProp(const TFloatProp& f): TCseObj(f.bArray()) { }
    TFloatProp(TDouble f): TCseObj(CseEmptyBuff) { append(TFloatObj(f)); append(TIntObj(0)); }

    void bindMethod(void *owner, void *AccessFunc=NULL) const
    { ASSERT_TRUE(len() == 2); m_data->bValue[1]->vValue = (CseObj)owner; m_data->bValue[1]->bHold = (CseObj)AccessFunc; }

    TFloatObj& fObj() const { return (TFloatObj&) m_data->bValue[0]->fValue; }

    const TFloatProp& operator=(const TFloatProp& f) const { TDouble ff = value_(); value_(&ff); return *this; }
    const TFloatProp& operator=(TDouble f) const { value_(&f); return *this; }

    operator TDouble() const { return value_(); }

    const TFloatProp& operator++() const { TDouble f = value_() + 1.0; value_(&f); return *this; }     // prefix
    const TFloatProp& operator++(int) const { TDouble f = value_() + 1.0; value_(&f); return *this; }  // postfix
    const TFloatProp& operator--() const { TDouble f = value_() - 1.0; value_(&f); return *this; }     // prefix
    const TFloatProp& operator--(int) const { TDouble f = value_() - 1.0; value_(&f); return *this; }  // postfix

    void operator*=(TDouble f) const { f = value_() * f; value_(&f); }
    void operator/=(TDouble f) const { f = value_() / f; value_(&f); }
    void operator+=(TDouble f) const { f = value_() + f; value_(&f); }
    void operator-=(TDouble f) const { f = value_() - f; value_(&f); }
    
    TDouble operator*(TDouble f) const { return value_() * f; }
    TDouble operator/(TDouble f) const { return value_() / f; }
    TDouble operator+(TDouble f) const { return value_() + f; }
    TDouble operator-(TDouble f) const { return value_() - f; }
};

extern CSE_IMPEXP_IN TDouble operator*(TDouble f1,const TFloatProp& f2);
extern CSE_IMPEXP_IN TDouble operator/(TDouble f1,const TFloatProp& f2);
extern CSE_IMPEXP_IN TDouble operator+(TDouble f1,const TFloatProp& f2);
extern CSE_IMPEXP_IN TDouble operator-(TDouble f1,const TFloatProp& f2);

class CSE_IMPEXP_IN TStrProp: public TCseObj
{
private:
#ifndef MNG_OPEN_NEWDEL
    TStrProp *operator&();     // get prop-value address disabled
#endif
    TXchar* value_(const TXchar** pValue=NULL) const
    {
        CseObj v = m_data->bValue[1];
        if (v->bHold)
            return ((TXchar* (*)(CseObj,TCharArray&,const TXchar**))v->bHold)(v->vValue,(TCharArray&)m_data->bValue[0]->sValue,pValue);
        else {
            TCharArray& s = sub(0).sArray();
            if (pValue != NULL)
                s = *pValue;
            return s.addr();
        }
    }

public:
    TStrProp(): TCseObj(CseEmptyBuff) { append(CseEmptyStr); append(TIntObj(0)); }
    TStrProp(const TStrProp& s): TCseObj(s.bArray()) { }
    TStrProp(const TCharArray& s): TCseObj(CseEmptyBuff) { append(s); append(TIntObj(0)); }
    TStrProp(const TXchar* pSour):TCseObj(CseEmptyBuff) { TCharArray s(pSour); append(TCseObj(CUT_FROM,s)); append(TIntObj(0)); }

    void bindMethod(void *owner, void *AccessFunc=NULL) const
    { ASSERT_TRUE(len() == 2); m_data->bValue[1]->vValue = (CseObj)owner; m_data->bValue[1]->bHold = (CseObj)AccessFunc; }

    TCharArray& sArray() const { return (TCharArray&) m_data->bValue[0]->sValue; }
    
    const TStrProp& operator=(const TStrProp& str) const { const TXchar *s = str.value_(); value_(&s); return *this; }
    const TStrProp& operator=(const TCharArray& str) const { const TXchar *s = str.addr(); value_(&s); return *this; }
    const TStrProp& operator=(const TXchar *s) const { value_(&s); return *this; }

    operator TXchar*() const { return value_(); }
    
    TCharArray operator+(const TStrProp& y) const { TCharArray s = value_(); s += y.value_(); return TCharArray(CUT_FROM,s); }
    TCharArray operator+(const TXchar *y) const { TCharArray s = value_(); s += y; return TCharArray(CUT_FROM,s); }
    TCharArray operator+(TXchar y) const { TCharArray s = value_(); s += y; return TCharArray(CUT_FROM,s); }
    TCharArray operator+(const TCharArray& y) const { return value_() + y; }

    TBool operator==(const TXchar *y) const { TCharArray s = value_(); return s == y; }
    TBool operator!=(const TXchar *y) const { TCharArray s = value_(); return s != y; }
    TBool operator>(const TXchar *y) const { TCharArray s = value_(); return s > y; }
    TBool operator>=(const TXchar *y) const { TCharArray s = value_(); return s >= y; }
    TBool operator<(const TXchar *y) const { TCharArray s = value_(); return s < y; }
    TBool operator<=(const TXchar *y) const { TCharArray s = value_(); return s <= y;  }
};

extern CSE_IMPEXP_IN TCharArray operator+(TXchar x, const TStrProp& y);
extern CSE_IMPEXP_IN TCharArray operator+(const TXchar *x, const TStrProp& y);
extern CSE_IMPEXP_IN TCharArray operator+(const TCharArray& x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator==(const TXchar *x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator==(const TCharArray& x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator!=(const TXchar *x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator!=(const TCharArray& x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator>(const TXchar *x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator>(const TCharArray& x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator>=(const TXchar *x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator>=(const TCharArray& x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator<(const TXchar *x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator<(const TCharArray& x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator<=(const TXchar *x, const TStrProp& y);
extern CSE_IMPEXP_IN TBool operator<=(const TCharArray& x, const TStrProp& y);

template<class T> class TMngPointer: public TCseObj
{
public:
    TMngPointer(): TCseObj(TIntObj(0)) { }
    T *operator->() { return (T*) m_data->vValue; }
};

template<class T> class TMngHolder: public TMngBuff
{
#ifndef MNG_OPEN_NEWDEL
private:
    static void* operator new(size_t);
    static void* operator new(size_t,int);
    static void operator delete(void*);
    static void operator delete(void*,size_t);
    const TMngHolder* operator&() const;
#endif
public:
    void __exit__() {
        if (len() >= 2) {
            T* pObj = (T*) m_data->bValue[1]->vValue;
            if (pObj) delete pObj;
        }
        clear();
    }

    TMngHolder(T* pObj) {
        if (len() < 2) resize(2);
        setExitFunc(METHOD_ADDR(TMngHolder,__exit__));
        sub(1) = TIntObj((TInt)pObj);
    }

    TMngHolder(CseObj obj): TMngBuff(obj) { }
    TMngHolder(const TCseObj& obj): TMngBuff(obj.m_data) { }
    TMngHolder(const TMngHolder& obj): TMngBuff(obj.m_data) { }
    TMngHolder() { }
    
    TMngHolder& operator=(T* pObj) {
        if (len() < 2) resize(2); 
        setExitFunc(METHOD_ADDR(TMngHolder,__exit__)); 
        sub(1) = TIntObj((TInt)pObj);
        return *this;
    }

    TMngHolder& operator=(const TMngHolder& obj) {
        *(TCseObj*)&m_data = obj.m_data;
        return *this;
    }
    
    class m: public TMngBuff::m { private: m(); m(const m& obj); public: TMngPointer<T> __base__; };
    T *operator->() { return (T*) m_data->bValue[1]->vValue; }
};

template<class T> class TExiting
{
private:
    T *m_obj;
    void (T::* m_func)();
    
public:
    TExiting(T* obj,void (T::* AFunc)()) { m_obj = obj; m_func = AFunc; }
    ~TExiting() { (m_obj->*m_func)(); }
};

#endif
